import { Platform } from 'react-native';
import {
  Product,
  ProductPurchase,
  Subscription,
  SubscriptionPurchase,
  clearTransactionIOS,
  endConnection,
  finishTransaction,
  flushFailedPurchasesCachedAsPendingAndroid,
  getAvailablePurchases,
  getProducts,
  getSubscriptions,
  initConnection,
  purchaseErrorListener,
  purchaseUpdatedListener,
  requestPurchase,
  requestSubscription,
  PurchaseError,
} from 'react-native-iap';

import { get } from 'lodash';

// Import required types from react-native-iap
type SubscriptionAndroid = Subscription & { productType: string };
type SubscriptionIOS = Subscription & { type: string };
type ProductAndroid = Product & { productType: string };
type ProductIOS = Product & { type: string };

export interface PurchaseParams {
  product: Product | Subscription;
  skus: string[];
  appAccountToken?: string;
  orderId: Payment.PaymentOrderID; // 安卓谷歌支付需要携带业务订单id
  userId?: string; // 安卓谷歌支付需要携带用户id，用于续订
  env: 'test' | 'prod'; // 支付环境,后端服务正式环境就使用prod
  businessProductCode?: string;
}

/**
 * 移动端苹果支付和谷歌支付SDK封装
 * 基于react-native-iap库的封装
 */
export class PaymentSDK {
  /**
   * 访问修饰符说明：
   * private：用于类的内部实现细节；不希望外部访问的方法和属性；只能在类内部使用；
   * public：类的对外接口；需要被外部调用的方法；默认修饰符（可以省略）
   * static：类级别的方法和属性（不需要实例化就能使用）；全局共享的状态或功能
   */
  // 添加错误类型定义
  private static readonly ERROR_CODES = {
    CONNECTION_FAILED: 'CONNECTION_FAILED',
    PURCHASE_FAILED: 'PURCHASE_FAILED',
    INVALID_PRODUCT: 'INVALID_PRODUCT',
  } as const;

  private static instance: PaymentSDK | null = null;
  private initialized: boolean = false;
  static connectionStatus = false;

  private constructor() {}

  /**
   * PaymentSDK初始化
   */

  private async initialize() {
    if (this.initialized) return;

    try {
      await initConnection();
      await PaymentSDK.clearTransaction();
      PaymentSDK.connectionStatus = true;
      this.initialized = true;
    } catch (error) {
      console.error('Failed to initialize PaymentSDK:', error);
      throw new Error(PaymentSDK.ERROR_CODES.CONNECTION_FAILED);
    }
  }

  /**
   * 获取PaymentSDK实例
   */
  static async getInstance(): Promise<PaymentSDK> {
    if (!PaymentSDK.instance) {
      PaymentSDK.instance = new PaymentSDK();
      await PaymentSDK.instance.initialize();
    }
    return PaymentSDK.instance;
  }

  /**
   * 清除幽灵订单（即已经失败但在 Play Store/App Store 缓存中仍标记为待处理的待处理付款）
   */
  static clearTransaction() {
    if (Platform.OS === 'android') {
      flushFailedPurchasesCachedAsPendingAndroid();
    } else if (Platform.OS === 'ios') {
      clearTransactionIOS();
    }
  }

  /**
   * 获取所有产品 (从Apple Store/Google Play获取)
   * @param skus
   */
  async getAllProductsFromStore(skus: string[]) {
    try {
      if (Platform.OS === 'android') {
        const sub = await getSubscriptions({ skus });
        const nonSub = await getProducts({ skus });
        return [...sub, ...nonSub];
      }
      return getProducts({ skus });
    } catch (error) {
      console.error('Failed to get products:', error);
      throw new Error(PaymentSDK.ERROR_CODES.INVALID_PRODUCT);
    }
  }

  /**
   * 从Store中完成订单
   * @param purchase
   * @param isConsumable
   * @param developerPayloadAndroid
   */
  finishTransaction(
    purchase: ProductPurchase | SubscriptionPurchase,
    isConsumable = false,
    developerPayloadAndroid?: string,
  ) {
    return finishTransaction({ purchase, isConsumable, developerPayloadAndroid });
  }

  getAvailablePurchases() {
    return getAvailablePurchases();
  }

  addPurchaseUpdatedListener = purchaseUpdatedListener;

  addPurchaseErrorListener = purchaseErrorListener;

  /**
   * 关闭链接
   */
  async endPaymentSDKConnection() {
    try {
      await endConnection();
      this.initialized = false;
      PaymentSDK.connectionStatus = false;
      PaymentSDK.instance = null;
    } catch (error) {
      console.error('endPaymentSDKConnection failed:', error);
    }
  }

  /**
   * 获取从Store获取的产品（应用内商品或者订阅产品）的价格和货币
   * @param productForStore
   */
  getProductPriceAndCurrency(productForStore?: Subscription | Product) {
    if (!productForStore) return;

    if (this.isInappProduct(productForStore)) {
      const priceAmountMicros = +get(productForStore, 'oneTimePurchaseOfferDetails.priceAmountMicros', '0');
      const price = priceAmountMicros / 1000000;
      const currency = get(productForStore, 'oneTimePurchaseOfferDetails.priceCurrencyCode', 'USD');
      return { price, currency };
    } else if (this.isSubscriptionProduct(productForStore)) {
      const priceAmountMicros = +get(
        productForStore,
        'subscriptionOfferDetails.0.pricingPhases.pricingPhaseList.0.priceAmountMicros',
        '0',
      );
      const price = priceAmountMicros / 1000000;
      const currency = get(
        productForStore,
        'subscriptionOfferDetails.0.pricingPhases.pricingPhaseList.0.priceCurrencyCode',
        'USD',
      );
      return { price, currency };
    }
  }

  /**
   * 判断是否是应用内商品(android端)，或app内购买项目(IOS端)
   */
  isInappProduct(product: Product | Subscription | undefined): product is Product {
    if (!product) return false;
    if (Platform.OS === 'android') {
      return ['inapp', 'iap'].includes((product as ProductAndroid).productType);
    }
    return ['inapp', 'iap'].includes((product as ProductIOS).type);
  }

  /**
   * 判断是否是订阅(android端)，或订阅(IOS端)
   * */
  isSubscriptionProduct(product: Product | Subscription | undefined): product is Subscription {
    if (!product) return false;
    if (Platform.OS === 'android') {
      return ['sub', 'subs'].includes((product as SubscriptionAndroid).productType);
    }
    return ['sub', 'subs'].includes((product as SubscriptionIOS).type);
  }

  /**
   * 发起订阅产品支付
   */
  async purchaseSubscribeProduct(params: PurchaseParams) {
    const { product, appAccountToken, orderId, userId, env } = params;

    // 参数验证
    if (!params.product) {
      throw new Error(PaymentSDK.ERROR_CODES.INVALID_PRODUCT);
    }

    if (Platform.OS === 'android') {
      const productId = product.productId;
      // TODO 默认选中第一个
      const offerToken = (product as Subscription & Product)?.subscriptionOfferDetails?.[0]?.offerToken;
      return requestSubscription({
        sku: productId,
        ...(offerToken && {
          subscriptionOffers: [{ sku: productId, offerToken }],
        }),
        appAccountToken: appAccountToken,
        //   android,将业务订单id传递给谷歌支付
        obfuscatedProfileIdAndroid: JSON.stringify({
          environment: env || 'test',
          orderId: orderId?.toString(),
        }),
        // android,用于续订
        obfuscatedAccountIdAndroid: userId,
      });
    } else if (Platform.OS === 'ios') {
      const productId = product.productId;
      return requestSubscription({
        sku: productId,
        appAccountToken: appAccountToken,
      });
    }
  }

  /** 购买产品（一次性支付）*/
  async purchaseInappProduct(params: PurchaseParams) {
    const { product, skus, appAccountToken, orderId, userId, env } = params;

    // 参数验证
    if (!params.product || !params.skus?.length) {
      throw new Error(PaymentSDK.ERROR_CODES.INVALID_PRODUCT);
    }

    // 断言返回一个ProductPurchase
    return requestPurchase({
      sku: product.productId,
      skus: skus,
      appAccountToken: appAccountToken,
      //   android,将业务订单id传递给谷歌支付
      obfuscatedProfileIdAndroid: JSON.stringify({
        environment: env || 'test',
        orderId: orderId?.toString(),
      }),
      // android,用于续订
      obfuscatedAccountIdAndroid: userId,
    });
  }

  /**
   * 发起支付(苹果支付、谷歌支付)，包括内购商品或订阅
   */
  async requestPurchase(params: PurchaseParams) {
    try {
      if (this.isSubscriptionProduct(params.product)) {
        return this.purchaseSubscribeProduct({
          product: params.product,
          appAccountToken: params.appAccountToken,
          orderId: params.orderId,
          userId: params.userId,
          env: params.env || 'test',
          skus: params.skus,
        });
      } else if (this.isInappProduct(params.product)) {
        return this.purchaseInappProduct({
          product: params.product,
          skus: params.skus,
          appAccountToken: params.appAccountToken,
          orderId: params.orderId,
          userId: params.userId,
          env: params.env || 'test',
        });
      }
    } catch (error) {
      console.error('Purchase failed:', error);
      throw new Error(PaymentSDK.ERROR_CODES.PURCHASE_FAILED);
    }
  }
}
